package com.controller.system;

import com.common.ResultUtil;
import com.common.WebContextHelper;
import com.common.stereotype.Module;
import com.common.stereotype.Token;
import com.common.stereotype.Uri;
import com.controller.base.BaseLocalController;
import com.entity.Manager;
import com.entity.Menu;
import com.entity.Role;
import com.entity.Source;
import com.facade.menu.IMenuFacadeR;
import com.facade.role.IRoleFacadeCUD;
import com.facade.role.IRoleFacadeR;
import com.facade.source.ISourceFacadeR;
import com.query.DefaultQuery;
import com.vo.SourceGroupVO;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Controller
@RequestMapping("/role")
//@Module(parent = "系统模块", name = "角色管理", parentModuleOrder = 0, childModuleOrder = 2)
public class RoleController extends BaseLocalController {

    @Resource
    private IRoleFacadeR roleFacadeR;
    @Resource
    private IRoleFacadeCUD roleFacadeCUD;
    @Resource
    private IMenuFacadeR menuFacadeR;
    @Resource
    private ISourceFacadeR sourceFacadeR;

    @ModelAttribute
    public void prepare(Long id, ModelMap modelMap) {
        HttpServletRequest request = WebContextHelper.getRequest();
        String requestUri = request.getRequestURI();
        if (requestUri.contains("modify") && null != id) {
            modelMap.addAttribute(roleFacadeR.findByPrimaryKey(id));
        }
    }

    @RequestMapping(value = "/query.htm")
    @Uri(name = "查询", uri = "/role/query", order = 0)
    public String query(@ModelAttribute("query") DefaultQuery query, ModelMap modelMap) {
        modelMap.addAttribute("paging", roleFacadeR.queryPage(query));
        return "system/role-List";
    }

    @RequestMapping(value = "/edit.htm")
    public String edit(Long id, ModelMap modelMap) {
        if (null != id) {
            modelMap.addAttribute(roleFacadeR.findByPrimaryKey(id));
        }
        return "system/role-edit";
    }

    @Token
    @ResponseBody
    @RequestMapping(value = "/add.htm", method = RequestMethod.POST)
    @Uri(name = "添加", uri = "/role/add", order = 1)
    public ResultUtil add(@Valid Role role, BindingResult error) {
        ResultUtil resultUtil = validate(error);
        if (ResultUtil.SUCCESS != resultUtil.getStatus()) {
            return resultUtil;
        }
        Manager onLineUser = WebContextHelper.getOnLineUser();
        return roleFacadeCUD.addRole(role, onLineUser.getId());
    }

    @Token
    @ResponseBody
    @RequestMapping(value = "/modify.htm", method = RequestMethod.POST)
    @Uri(name = "修改", uri = "/role/modify", order = 2)
    public ResultUtil modify(@Valid Role role, BindingResult error) {
        ResultUtil resultUtil = validate(error);
        if (ResultUtil.SUCCESS != resultUtil.getStatus()) {
            return resultUtil;
        }
        Manager onLineUser = WebContextHelper.getOnLineUser();
        return roleFacadeCUD.modifyRole(role, onLineUser.getId());
    }

    @RequestMapping(value = "/editSource.htm/{id}")
    public String editSource(@PathVariable("id") Long id, ModelMap modelMap) {
        List<Source> sourceList = sourceFacadeR.findAll("parent_module_order ASC, parent_module ASC, child_module_order ASC, child_module ASC, seq ASC");
        if (null != id) {
            Role role = roleFacadeR.findByPrimaryKey(id);
            if (null != role) {
                List<Source> roleSourceList = sourceFacadeR.findByRoleLink(id);
                List<Long> roleSourceIdList = new ArrayList<>();
                for (Source source : roleSourceList) {
                    roleSourceIdList.add(source.getId());
                }
                for (Source source : sourceList) {
                    if (roleSourceIdList.contains(source.getId())) {
                        source.setChecked(true);
                    }
                }
                modelMap.addAttribute("role", role);
            }
        }
        Map<String, SourceGroupVO> map = new LinkedHashMap<>();
        for (Source source : sourceList) {
            String childModule = source.getChildModule();
            SourceGroupVO sourceGroupVO = map.get(childModule);
            if (null == sourceGroupVO) {
                sourceGroupVO = new SourceGroupVO(source.getParentModule(), childModule);
                map.put(childModule, sourceGroupVO);
            }
            sourceGroupVO.getSourceList().add(source);
        }

        String parentModule;
        SourceGroupVO sourceGroupVO;
        SourceGroupVO sourceGroupVO$;
        Map<String, Boolean> checkedMap = new HashMap<>();
        Set<String> parentModuleSet = new HashSet<>();
        List<SourceGroupVO> sourceGroupVOList = new ArrayList<>();
        for (Map.Entry<String, SourceGroupVO> entry : map.entrySet()) {
            sourceGroupVO = entry.getValue();
            parentModule = sourceGroupVO.getParentModule();
            boolean checked = sourceGroupVO.getChecked();
            if (!checked) {
                checkedMap.put(parentModule, false);
            }
            if (!parentModuleSet.contains(parentModule)) {
                parentModuleSet.add(parentModule);
                sourceGroupVO$ = new SourceGroupVO(parentModule, null);
                sourceGroupVO$.setVirtual(true);
                sourceGroupVOList.add(sourceGroupVO$);
            }
            sourceGroupVOList.add(sourceGroupVO);
        }
        for (SourceGroupVO groupVO : sourceGroupVOList) {
            if (groupVO.isVirtual()) {
                if (null != checkedMap.get(groupVO.getParentModule())) {
                    groupVO.setChecked(false);
                }
            }
        }
        modelMap.addAttribute("sourceGroupList", sourceGroupVOList);
        return "system/role-source";
    }

    @Token
    @ResponseBody
    @RequestMapping(value = "/modifySource.htm/{id}", method = RequestMethod.POST)
    @Uri(name = "权限管理", uri = "/role/modifySource", order = 3)
    public ResultUtil modifyRoleSource(@PathVariable("id") Long id, Long[] sourceId) {
        Manager onLineUser = WebContextHelper.getOnLineUser();
        return roleFacadeCUD.modifyRoleSource(id, sourceId, onLineUser.getId());
    }

    @RequestMapping(value = "/editMenu.htm/{id}")
    public String editMenu(@PathVariable("id") Long id, ModelMap modelMap) {
        Role role = roleFacadeR.findByPrimaryKey(id);
        if (null != role) {
            modelMap.addAttribute("role", role);
            List<Menu> menuList = menuFacadeR.findAll("seq ASC");
            List<Menu> roleMenuList = menuFacadeR.findByRoleLink(id);
            List<Long> roleMenuIdList = new ArrayList<>();
            for (Menu menu : roleMenuList) {
                roleMenuIdList.add(menu.getId());
            }
            for (Menu menu : menuList) {
                if (roleMenuIdList.contains(menu.getId())) {
                    menu.setChecked(true);
                }
            }
            modelMap.addAttribute("menuList", menuFacadeR.findMenuLv(menuList));
        }
        return "system/role-menu";
    }

    /**
     * 编辑角色菜单
     *
     * @param id
     * @param menuId
     * @return
     */
    @Token
    @ResponseBody
    @RequestMapping(value = "/modifyMenu.htm/{id}", method = RequestMethod.POST)
    @Uri(name = "菜单管理", uri = "/role/modifyMenu", order = 4)
    public ResultUtil modifyRoleMenu(@PathVariable("id") Long id, Long[] menuId) {
        Manager onLineUser = WebContextHelper.getOnLineUser();
        return roleFacadeCUD.modifyRoleMenu(id, menuId, onLineUser.getId());
    }

    @ResponseBody
    @RequestMapping(value = "/delete.htm/{id}")
    @Uri(name = "删除", uri = "/role/delete", order = 5)
    public ResultUtil delete(@PathVariable("id") Long id) {
        Manager onLineUser = WebContextHelper.getOnLineUser();
        return roleFacadeCUD.deleteRole(id, onLineUser.getId());
    }

}